import { LLMAdapter, ModelInfo, ValidationResult, ValidationErrorCode } from '../../types/index';

export class OpenAICompatibleAdapter implements LLMAdapter {
  private readonly timeout = 10000; // 10秒超时

  async fetchModels(baseURL = 'https://api.openai.com/v1', apiKey?: string): Promise<ModelInfo[]> {
    // 如果提供了baseURL和apiKey，尝试从实际API获取模型列表
    if (baseURL && apiKey) {
      try {
        const modelsUrl = `${baseURL}/models`;
        const response = await this.makeRequest(modelsUrl, {
          method: 'GET',
          headers: {
            'Authorization': `Bearer ${apiKey}`,
            'Content-Type': 'application/json',
          },
        });

        if (response.ok) {
          const data = await response.json();
          if (data.data && Array.isArray(data.data)) {
            return this.parseModels(data.data, baseURL);
          }
        }
      } catch (error) {
        console.warn('Failed to fetch models from', baseURL, ':', error);
      }
    }
    
    // 如果无法从实际API获取，返回静态模型列表
    return this.getStaticModels();
  }

  async validateApiKey(apiKey: string, baseURL = 'https://api.openai.com/v1'): Promise<ValidationResult> {
    if (!apiKey || !apiKey.trim()) {
      return {
        isValid: false,
        error: {
          code: ValidationErrorCode.INVALID_API_KEY,
          message: 'API Key 不能为空',
          suggestion: '请输入有效的 API Key'
        }
      };
    }

    if (!baseURL || !baseURL.trim()) {
      return {
        isValid: false,
        error: {
          code: ValidationErrorCode.INVALID_API_KEY,
          message: 'Base URL 不能为空',
          suggestion: '请输入有效的 API 基础地址'
        }
      };
    }

    try {
      // 首先尝试获取模型列表
      const modelsResponse = await this.makeRequest(`${baseURL}/models`, {
        method: 'GET',
        headers: {
          'Authorization': `Bearer ${apiKey}`,
          'Content-Type': 'application/json',
        },
      });

      if (modelsResponse.ok) {
        const modelsData = await modelsResponse.json();
        return {
          isValid: true,
          metadata: {
            availableModels: modelsData.data?.map((m: any) => m.id) || []
          }
        };
      }

      // 如果获取模型列表失败，尝试简单的聊天请求
      const testPayload = {
        model: 'gpt-3.5-turbo', // 使用通用模型名
        messages: [{ role: 'user', content: 'test' }],
        max_tokens: 1
      };

      const chatResponse = await this.makeRequest(`${baseURL}/chat/completions`, {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${apiKey}`,
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(testPayload),
      });

      if (chatResponse.ok) {
        const chatData = await chatResponse.json();
        return {
          isValid: true,
          metadata: {
            model: chatData.model,
            usage: chatData.usage
          }
        };
      } else {
        const errorData = await chatResponse.json().catch(() => ({}));
        return this.handleErrorResponse(chatResponse.status, errorData);
      }
    } catch (error) {
      return this.handleNetworkError(error);
    }
  }

  private async makeRequest(url: string, options: RequestInit): Promise<Response> {
    const controller = new AbortController();
    const timeoutId = setTimeout(() => controller.abort(), this.timeout);

    try {
      const response = await fetch(url, {
        ...options,
        signal: controller.signal,
      });
      clearTimeout(timeoutId);
      return response;
    } catch (error) {
      clearTimeout(timeoutId);
      throw error;
    }
  }

  private parseModels(models: any[], baseURL: string): ModelInfo[] {
    return models
      .filter(model => model.id && typeof model.id === 'string')
      .map(model => ({
        id: model.id,
        name: model.id,
        provider: 'openai-compatible',
        description: model.description || `OpenAI Compatible model: ${model.id}`,
        contextLength: this.estimateContextLength(model.id),
        capabilities: this.estimateCapabilities(model.id),
      }))
      .sort((a, b) => a.name.localeCompare(b.name));
  }

  private estimateContextLength(modelId: string): number {
    // 根据模型id估算上下文长度
    const lowerModelId = modelId.toLowerCase();
    
    if (lowerModelId.includes('32k')) return 32768;
    if (lowerModelId.includes('16k')) return 16384;
    if (lowerModelId.includes('gpt-4')) return 8192;
    if (lowerModelId.includes('claude')) return 200000;
    if (lowerModelId.includes('llama')) return 4096;
    
    return 4096; // 默认值
  }

  private estimateCapabilities(modelId: string): string[] {
    const capabilities = ['text'];
    const lowerModelId = modelId.toLowerCase();
    
    if (lowerModelId.includes('gpt-4') || lowerModelId.includes('claude') || lowerModelId.includes('gemini')) {
      capabilities.push('advanced-reasoning');
    }
    
    if (lowerModelId.includes('vision') || lowerModelId.includes('4o')) {
      capabilities.push('vision');
    }
    
    if (lowerModelId.includes('code') || lowerModelId.includes('coding')) {
      capabilities.push('coding');
    }
    
    return capabilities;
  }

  private getStaticModels(): ModelInfo[] {
    return [
      {
        id: 'gpt-4',
        name: 'GPT-4',
        provider: 'openai-compatible',
        description: 'GPT-4 compatible model',
        contextLength: 8192,
        capabilities: ['text', 'advanced-reasoning'],
      },
      {
        id: 'gpt-4-turbo',
        name: 'GPT-4 Turbo',
        provider: 'openai-compatible',
        description: 'GPT-4 Turbo compatible model',
        contextLength: 128000,
        capabilities: ['text', 'advanced-reasoning'],
      },
      {
        id: 'gpt-3.5-turbo',
        name: 'GPT-3.5 Turbo',
        provider: 'openai-compatible',
        description: 'GPT-3.5 Turbo compatible model',
        contextLength: 4096,
        capabilities: ['text'],
      },
      {
        id: 'claude-3-sonnet',
        name: 'Claude 3 Sonnet',
        provider: 'openai-compatible',
        description: 'Claude 3 Sonnet compatible model',
        contextLength: 200000,
        capabilities: ['text', 'advanced-reasoning'],
      },
      {
        id: 'llama-3.1-70b',
        name: 'Llama 3.1 70B',
        provider: 'openai-compatible',
        description: 'Llama 3.1 70B compatible model',
        contextLength: 131072,
        capabilities: ['text', 'coding'],
      },
      {
        id: 'qwen-72b',
        name: 'Qwen 72B',
        provider: 'openai-compatible',
        description: 'Qwen 72B compatible model',
        contextLength: 32768,
        capabilities: ['text', 'multilingual'],
      },
    ];
  }

  private handleErrorResponse(status: number, errorData: any): ValidationResult {
    switch (status) {
      case 401:
        return {
          isValid: false,
          error: {
            code: ValidationErrorCode.INVALID_API_KEY,
            message: 'API Key 无效或已过期',
            suggestion: '请检查 API Key 是否正确，并确认账户状态正常'
          }
        };
      case 403:
        return {
          isValid: false,
          error: {
            code: ValidationErrorCode.INSUFFICIENT_PERMISSIONS,
            message: '权限不足或账户被限制',
            suggestion: '请检查账户状态和 API 使用权限'
          }
        };
      case 404:
        return {
          isValid: false,
          error: {
            code: ValidationErrorCode.SERVER_ERROR,
            message: 'API 端点不存在',
            suggestion: '请检查 Base URL 是否正确'
          }
        };
      case 429:
        return {
          isValid: false,
          error: {
            code: ValidationErrorCode.RATE_LIMITED,
            message: '请求频率过高',
            suggestion: '请降低请求频率或升级账户计划'
          }
        };
      case 500:
      case 502:
      case 503:
        return {
          isValid: false,
          error: {
            code: ValidationErrorCode.SERVER_ERROR,
            message: '服务器错误',
            suggestion: '请稍后重试'
          }
        };
      default:
        return {
          isValid: false,
          error: {
            code: ValidationErrorCode.UNKNOWN_ERROR,
            message: errorData.error?.message || '未知错误',
            suggestion: '请检查配置并重试'
          }
        };
    }
  }

  private handleNetworkError(error: any): ValidationResult {
    if (error.name === 'AbortError') {
      return {
        isValid: false,
        error: {
          code: ValidationErrorCode.TIMEOUT,
          message: '请求超时',
          suggestion: '请检查网络连接或稍后重试'
        }
      };
    }

    return {
      isValid: false,
      error: {
        code: ValidationErrorCode.NETWORK_ERROR,
        message: '网络连接错误',
        suggestion: '请检查网络连接和 Base URL 是否正确'
      }
    };
  }
}